package com.liqi.device.service.impl;

import com.liqi.common.annotation.DataScope;
import com.liqi.common.constant.UserConstants;
import com.liqi.common.utils.DateUtils;
import com.liqi.common.utils.StringUtils;
import com.liqi.deployment.domain.DvDeployment;
import com.liqi.deployment.domain.DvDeploymentModule;
import com.liqi.deployment.mapper.DvDeploymentMapper;
import com.liqi.deployment.mapper.DvDeploymentModuleMapper;
import com.liqi.device.domain.*;
import com.liqi.device.mapper.*;
import com.liqi.device.service.IDvDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 设备Service业务层处理
 *
 * @author zhongping
 * @date 2022-02-14
 */
@Service
public class DvDeviceServiceImpl implements IDvDeviceService {
    @Autowired
    private DvDeviceMapper dvDeviceMapper;

    @Autowired
    private DvModuleMapper dvModuleMapper;

    @Autowired
    private DvDeviceModuleMapper dvDeviceModuleMapper;

    @Autowired
    private DvDeploymentMapper dvDeploymentMapper;

    @Autowired
    private DvDeploymentModuleMapper dvDeploymentModuleMapper;

    /**
     * 查询设备
     *
     * @param id 设备主键
     * @return 设备
     */
    @Override
    public DvDevice selectDvDeviceById(Long id) {
        return dvDeviceMapper.selectDvDeviceById(id);
    }

    @Override
    public DvDevice selectDvDeviceByCode(String code) {
        return dvDeviceMapper.selectDvDeviceByCode(code);
    }

    @Override
    public DvDevice selectDvDeviceByDeviceId(String deviceId) {
        DvDeployment dvDeployment = dvDeploymentMapper.selectDvDeploymentByDeviceId(deviceId);
        if (dvDeployment != null) {
            String deviceCode = dvDeployment.getDeviceCode();
            return selectDvDeviceByCode(deviceCode);
        }
        return null;
    }

    @Override
    public List<String> selectDvNameList() {
        return dvDeviceMapper.selectDvNameList();
    }

    /**
     * 查询设备列表
     *
     * @param dvDevice 设备
     * @return 设备
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<DvDevice> selectDvDeviceList(DvDevice dvDevice) {
        return dvDeviceMapper.selectDvDeviceList(dvDevice);
    }

    @Override
    public List<DvDevice> queryDeviceList(DvDevice dvDevice) {
        return dvDeviceMapper.queryDeviceList(dvDevice);
    }

    @Override
    public List<DvDevice> queryDeviceListBysearchValue(String searchValue) {
        return dvDeviceMapper.queryDeviceListBysearchValue(searchValue);
    }

    /**
     * 新增设备
     *
     * @param dvDevice 设备
     * @return 结果
     */
    @Transactional
    @Override
    public int insertDvDevice(DvDevice dvDevice) {
        dvDevice.setCreateTime(DateUtils.getNowDate());
        int d = dvDeviceMapper.insertDvDevice(dvDevice);
        //插入 设备-模块关联表 dv_device_module
        if (dvDevice.getModules() != null && dvDevice.getModules().size() > 0) {
            List<DvDeviceModule> dvDeviceModules = new ArrayList<>();
            for (DvModule module : dvDevice.getModules()) {
                DvDeviceModule dm = new DvDeviceModule();
                dm.setDeviceCode(dvDevice.getCode());
                dm.setModuleCode(module.getCode());
                dm.setModuleName(module.getName());
                dvDeviceModules.add(dm);
            }
            dvDeviceModuleMapper.insertDvDeviceModuleBatch(dvDeviceModules);
        }
        return d;
    }

    /**
     * 修改设备
     *
     * @param dvDevice 设备
     * @return 结果
     */
    @Transactional
    @Override
    public int updateDvDevice(DvDevice dvDevice) {
        DvDevice oldDevice = dvDeviceMapper.selectDvDeviceById(dvDevice.getId());

        dvDevice.setUpdateTime(DateUtils.getNowDate());
        //update 表dv_device
        int cnt = dvDeviceMapper.updateDvDevice(dvDevice);

        //根据旧的device_code 删除表dv_device_module
        dvDeviceModuleMapper.deleteDvDeviceModuleByDeviceCode(oldDevice.getCode());

        //重新插入表dv_device_module
        if (dvDevice.getModules() != null && dvDevice.getModules().size() > 0) {
            List<DvDeviceModule> dvDeviceModules = new ArrayList<>();
            for (DvModule module : dvDevice.getModules()) {
                DvDeviceModule dm = new DvDeviceModule();
                dm.setDeviceCode(dvDevice.getCode());
                dm.setModuleCode(module.getCode());
                dm.setModuleName(module.getName());
                dvDeviceModules.add(dm);
            }
            dvDeviceModuleMapper.insertDvDeviceModuleBatch(dvDeviceModules);
        }

        //更新投放管理
        List<DvDeployment> dvDeployments = dvDeploymentMapper.selectDvDeploymentByDeviceCode(oldDevice.getCode());
        for(DvDeployment dvDeployment:dvDeployments) {
            if (dvDeployment != null) {
                String deviceId = dvDeployment.getDeviceId();
                //先删除
                dvDeploymentModuleMapper.deleteDvDeploymentModuleByDeviceId(deviceId);
                //重新插入表dv_deploy_device_model
                if (dvDevice.getModules() != null && dvDevice.getModules().size() > 0) {
                    for (DvModule module : dvDevice.getModules()) {
                        DvDeploymentModule ddm = new DvDeploymentModule();
                        ddm.setDeviceId(deviceId);
                        ddm.setDeviceCode(dvDevice.getCode());
                        ddm.setDeviceName(dvDevice.getName());
                        ddm.setModelCode(module.getCode());
                        ddm.setModelName(module.getName());
                        ddm.setModelStatus(module.getStatus());
                        ddm.setStatus(module.getStatus());
                        ddm.setCreateBy(dvDevice.getUpdateBy());
                        ddm.setCreateTime(new Date());
                        ddm.setUpdateBy(dvDevice.getUpdateBy());
                        ddm.setUpdateTime(new Date());
                        dvDeploymentModuleMapper.insertDvDeploymentModule(ddm);
                    }
                }
            }
        }
        return cnt;
    }

    /**
     * 批量删除设备
     *
     * @param ids 需要删除的设备主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDvDeviceByIds(Long[] ids) {
        List<DvDevice> oldDevices = dvDeviceMapper.selectDvDeviceListByIds(ids);
        int d = dvDeviceMapper.deleteDvDeviceByIds(ids);
        if (d > 0) {
            oldDevices.forEach(p -> {
                dvDeviceModuleMapper.deleteDvDeviceModuleByDeviceCode(p.getCode());
            });
        }
        return d;
    }

    /**
     * 删除设备信息
     *
     * @param id 设备主键
     * @return 结果
     */
    @Override
    public int deleteDvDeviceById(Long id) {
        return dvDeviceMapper.deleteDvDeviceById(id);
    }

    /**
     * 校验编码是否唯一
     *
     * @param dvDevice 需校验的
     * @return 结果
     */
    @Override
    public String checkCodeUnique(DvDevice dvDevice) {
        Long configId = StringUtils.isNull(dvDevice.getId()) ? -1L : dvDevice.getId();
        DvDevice info = dvDeviceMapper.checkCodeUnique(dvDevice.getCode());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != configId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;

    }

    /**
     * 根据id查询设备投放信息
     *
     * @param ids
     * @return 结果
     */
    @Override
    public List<DvDevice> selectDvDeviceListByIds(Long[] ids) {
        return dvDeviceMapper.selectDvDeviceListByIds(ids);
    }

    @Override
    public String importDevice(List<DvDeviceExcel> dvDevices) {
        StringBuilder sb=new StringBuilder();
        for (DvDeviceExcel dvDevice : dvDevices) {
            if (isFieldNotNull(dvDevice)) {
                if(dvDeviceMapper.selectDvDeviceByCode(dvDevice.getCode())==null) {
                        dvDeviceMapper.insertDvDevice(dvDevice);
                }else {
                    dvDeviceMapper.updateDvDevice(dvDevice);
                }

            }else {
                sb.append("第" + dvDevice.getRowNum() + "行有值未填,");
                if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ',') {
                    sb.deleteCharAt(sb.length() -1 );
                }
                sb.append(";<br/>");
            }

        }
        return sb.toString();

    }

    /**
     * 判断一个实体类对象实例的所有成员变量是否为空
     *
     * @param obj 校验的类对象实例
     * @throws Exception
     */

    public static boolean isFieldNotNull(Object obj){
        //拿到对象的所有字段
        Field[] fields = obj.getClass().getDeclaredFields();
        //标识
        boolean flag = true;
        //遍历所有字段
        for (Field field : fields) {
            try {
                //开启权限
                field.setAccessible(true);
                //判断是否有值
                if (StringUtils.isEmpty(field.get(obj).toString())){
                    flag=false;
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                //关闭权限
                field.setAccessible(false);
            }
        }
        return flag;
    }

}